package com.jfl.web.controller.system;

import java.util.Arrays;
import java.util.Collection;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.crazycake.shiro.IRedisManager;
import org.crazycake.shiro.exception.SerializationException;
import org.crazycake.shiro.serializer.RedisSerializer;
import org.crazycake.shiro.serializer.StringSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import com.jfl.annotation.Log;
import com.jfl.base.AbstractController;
import com.jfl.common.Constants;
import com.jfl.common.MessageKey;
import com.jfl.config.Resources;
import com.jfl.enums.LogType;
import com.jfl.enums.Module;
import com.jfl.exception.BusinessException;
import com.jfl.model.SysSession;
import com.jfl.system.SysSessionService;
import com.jfl.utils.ConvertRequestUtil;
import com.jfl.utils.ConvertUtil;

/**
 * 会话管理
 * 后期增加模块
 * 
 * @author 赵炎
 * @version [V1.00, 2018年12月11日]
 * @since V1.00
 */
@Controller
@RequestMapping("${jfl.module.system}/session")
public class SysSessionController extends AbstractController
{
    @Reference(version = "${jfl.version}")
    private SysSessionService sysSessionService;
    
    @Autowired
    private IRedisManager redisManager;
    
    @SuppressWarnings("rawtypes")
    private RedisSerializer keySerializer = new StringSerializer();
    
    @Value("${jfl.shiro.cache.prefix}")
    private String keyPrefix;
    
    @Value("${jfl.demoMode}")
    private boolean mode;
    /**
     * 界面
     * 
     * @return
     */
    @RequiresPermissions("system:session:view")
    @GetMapping
    public String view()
    {
        return Constants.MODULE_SESSION_PREFIX + "session";
    }
    
    /**
     * 列表
     * 
     * @param session
     * @return
     */
    @RequiresPermissions("system:session:list")
    @PostMapping("/list")
    @ResponseBody
    public ResponseEntity<ModelMap> list(SysSession session)
    {
        PageInfo<SysSession> pageInfo = this.sysSessionService.selectList(ConvertRequestUtil.pageRequest(), session);
        return setSuccessModelMap(pageInfo);
    }
    
    /**
     * 列表
     * 
     * @param session
     * @return
     */
    @SuppressWarnings("unchecked")
    @Log(module = Module.SESSION, value = "会话管理", type = LogType.DELETE)
    @RequiresPermissions("system:session:remove")
    @PostMapping("/remove")
    @ResponseBody
    public ResponseEntity<ModelMap> remove(String ids)
    {
        if(mode) 
        {
            throw new BusinessException("演示模式，不允许操作！");
        }
        Collection<SysSession> list = this.sysSessionService.listByIds(Arrays.asList(ConvertUtil.toLongArray(ids)));
        // session 如果是管理员不让踢出
        for (SysSession sysSession : list)
        {
            if (sysSession.getCreateBy().longValue() == 1)
            {
                throw new BusinessException(Resources.getMessage(MessageKey.ADMIN_CANNOT_DELETE_SESSION));
            }
        }
        try
        {
            for (SysSession sysSession : list)
            {
                // 缓存session清除
                this.redisManager.del(keySerializer.serialize(getRedisSessionKey(sysSession.getSessionId())));
                // 权限缓存
                this.redisManager.del(keySerializer.serialize("*" + sysSession.getCreateBy()));
            }
            // 数据库清除
            // 批量删除
            this.sysSessionService.removeByIds(Arrays.asList(ConvertUtil.toLongArray(ids)));
        }
        catch (SerializationException e)
        {
            throw new BusinessException(Resources.getMessage(MessageKey.KICK_OUT_FAILED));
        }
        return setSuccessModelMap();
    }
    
    /**
     * session
     * 
     * @param id
     * @return
     */
    private Object getRedisSessionKey(String id)
    {
        return keyPrefix + id;
    }
}
